// (C) Andrea Giammarchi
(function($){$(function(){

	function APCQuery(){
		var	i = 0,
			ids = [];
		$(this).find("input").filter("[type=file]").each(function(){
			$(this).before(
				'<input type="hidden" name="APC_UPLOAD_PROGRESS[]" value="' +
					(ids[i++] = i + Math.random()) +
				'" />'
			);
		});
		$(this.parentNode).append(
			'<iframe class="apcquery" name="' + 
				(this.target = "apcqueryiframe" + ids.join("-")) +
			'" id="'
				+ this.target +
			'" src="' +
				(this.action = this.action.split("?")[0]) +
			'"></iframe>'
		);
		$(this).submit(function(){
			var	result = !!$(this).find("input").filter("[type=file]").filter(function(){return !!this.value}).length;
			if(result){
				var	delay = 500,
					timeout = 0,
					apcquery = $(this).find("div.apcquery"),
					iframe = $(this.parentNode).find("iframe[name=" + this.target + "]").get(0),
					self = this,
					onload = function(){
						iframe.onload = iframe.onreadystatechange = function(){};
						clearTimeout(timeout);
						APCResult(apcquery, iframe.contentWindow.response, function(){
							setTimeout(function(){
								$(self).find("input[type=submit]").each(function(){
									this.disabled = false;
								});
								apcquery.css("visibility", "hidden");
							}, delay);
						});
					};
				iframe.onreadystatechange = function(){
					if(/loaded|complete/i.test(iframe.readyState))
						onload();
				};
				iframe.onload = onload;
				$(this).find("input[type=submit]").each(function(){
					this.disabled = true;
				});
				apcquery.find(".percent").css("width", "0%");
				apcquery.css("visibility", "visible").find(".total,.loaded,.rate").text(APCSize(0));
				timeout = setTimeout(function(){
					var	i = 0,
						result = [],
						callee = arguments.callee;
					$(self).find("input")
					.filter(function(){
						return	this.name === "APC_UPLOAD_PROGRESS[]"
					})
					.each(function(){
						result[i++] = 'APC_PK[]=' + this.value;
					});
					$.getJSON(self.action + "?" + result.join("&"), function(data){
						APCResult(apcquery, data, function(){
							timeout = setTimeout(callee, delay);
						})
					});
				}, delay);
			};
			return	result;
		});
	};
	
	function APCResult(div, data, callback){
		var	loaded = 0,
			total = 0,
			i = 0;
		if(!div.__APCRate)
			div.__APCRate = {
				time:new Date,
				value:0
			};
		while(i < data.length){
			if(data[i]){
				loaded += data[i].current;
				total += data[i].total;
			};
			++i;
		};
		div.__APCRate.value = loaded - div.__APCRate.value;
		div.find(".total").text(APCSize(total));
		div.find(".loaded").text(APCSize(loaded));
		div.find(".rate").text(APCSize(parseInt((div.__APCRate.value * 100) / (new Date - div.__APCRate.time)) || 0).replace(/bytes/, "b") + "ps");
		div.find(".percent").css("width", (Math.round((loaded * 100) / total) || 0)+ "%");
		div.__APCRate.time = new Date;
		if(callback)
			callback();
	};
	
	function APCSize(value){
		var	type = ["bytes", "Kb", "Mb", "Gb", "Tb", "Zb"],
			i = 0;
		while(value > 1024 && ++i)
			value /= 1024;
		return	(i ? value.toFixed(2) : Math.ceil(value)) + " " + type[i];
	};
	
	$("form").each(function(){
		if(0 < $(this).find("input").filter("[type=file]").length)
			APCQuery.call(this);
	});
	
	if(!Number.prototype.toFixed)
		Number.prototype.toFixed = function(max){
			var	result = Math.pow(10, parseInt(max)), tmp;
			result = String(Math.round(this * result) / result);
			if(max > 0){
				tmp = result.split(".");
				tmp[1] = (tmp[1] || "") + new Array(++max - (tmp[1] ? tmp[1].length : 0)).join("0");
				result = tmp.join(".");
			};
			return	result;
		};
})})(jQuery);